package com.cctc.ware;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/**
 * @Name CommandManager
 * @Description: [1.4.6] 方法注入
 * 应用场景：当一个有状态的单例 Bean A 需要使用（依赖）无状态的非单例（prototype）Bean B 时，如果使用默认的 IoC 容器实例化机制，则非单例（prototype）Bean B 在单例 Bean A 中只能存在一个副本，IoC 容器不能在每次需要 Bean B的时候为 Bean A提供一个新的实例，无法满足实际的应用场景。
 * 解决方案：放弃一些控制的反转，通过手动实现 ApplicationContextAware（IoC 容器感知接口），定义一个 Bean B 实例感知器，在每次 Bean A 需要 Bean B 进行一些处理操作时，从感知器中获取一个新的 Bean B 实例，然后为 Bean B 处理方法注入参数，完成处理。
 *
 * @Author: lichao
 * @Email: li2chao@126.com
 * @Date: 2024-01-14 15:29:29
 **/
public class CommandManager implements ApplicationContextAware {

    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 1. 从 IoC 容器中获取一个新的 Command 实例
     * @return com.cctc.ware.Command
     * @author lichao
     * @email li2chao@126.com
     * @date 2024/01/14 15:57:12
     */
    protected Command createCommand() {
        return applicationContext.getBean("command", Command.class);
    }

    /**
     * 2. 为 Command 实例的处理方法注入参数
     * @param commandState 环境参数
     * @return boolean 处理结果
     * @author lichao
     * @email li2chao@126.com
     * @date 2024/01/14 15:58:28
     */
    public Map<String, Object> process(Map<String, Object> commandState) {
        Command command = createCommand();
        commandState.put("command", command);
        command.setState(commandState);
        return command.execute();
    }

}

